﻿using System;
using System.Xml.Serialization;
using System.Text;
public class SomeException : ApplicationException
{
    // code 1 删除失败
    // code 2 修改失败，原因是没找到对应id的订单
    // code 3 修改失败，原因是修改后出现了重复订单
    private int code;
    public SomeException(string message, int code)
        : base(message)
    {
        this.code = code;
    }
    public int Code { get { return code; } }
}
public class OrderDetails
{
    public string ProductName;
    public int Quantity;
    public int Price;
    public OrderDetails()
    {
        ProductName = "productToBeCreate";
        Quantity = 0;
        Price = 0;
    }
    public OrderDetails(string productName, int quantity, int price)
    {
        ProductName = productName;
        Quantity = quantity;
        Price = price;
    }
    public override bool Equals(object? obj)
    {
        OrderDetails other = obj as OrderDetails;
        if (other.ProductName == ProductName 
            && other.Quantity == Quantity 
            && other.Price == Price)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public override string ToString()
    {
        return "订单明细：\n" + 
            "商品名称：" + ProductName + "\n" +
            "交易数量：" + Quantity + "\n" +
            "商品价格：" + Price + "\n";
    }
}
public class Order : IComparable
{
    public int Id;
    public string Customer;
    public int Sum;
    public OrderDetails Details;
    public Order()
    {
        Id = 0;
        Customer = "小明";
        Sum = 0;
        Details = new OrderDetails();
    }
    public Order(int id, string customer, int sum, string productName, int quantity, int price)
    {
        Id = id;
        Customer = customer;
        Sum = sum;
        Details = new OrderDetails(productName, quantity, price);
    }
    public override bool Equals(object? obj)
    {
        Order order = obj as Order;
        if (order.Id == Id 
            && order.Customer == Customer 
            && order.Sum == Sum 
            && order.Details.Equals(Details))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public override string ToString()
    {
        return "订单：\n" +
            "订单Id：" + Id + "\n" +
            "客户姓名：" + Customer + "\n" +
            "订单总价：" + Sum + "\n" +
            Details;            ;
    }
    public int CompareTo(object obj2)
    {
        if (obj2 is not Order)
            throw new ArgumentException();
        Order order = obj2 as Order;
        return Id.CompareTo(order.Id);
    }
}
public class OrderService
{
    public List<Order> data = new List<Order>();
    public void add()
    {
        Console.WriteLine("按顺序依次输入订单的(int)Id, (string)Customer, (int)Sum, (string)ProductName, (int)Quantity, (int)Price\n注意用回车符分隔");
        string str = Console.ReadLine();
        int id = Int32.Parse(str);
        string customer = Console.ReadLine();
        str = Console.ReadLine();
        int sum = Int32.Parse(str);
        string productName = Console.ReadLine();
        str = Console.ReadLine();
        int Quantity = Int32.Parse(str);
        str = Console.ReadLine();
        int Price = Int32.Parse(str);
        Order newOrder = new Order(id, customer, sum, productName, Quantity, Price);
        // 判断是否有重复订单
        bool repeat = false;
        foreach (Order item in data)
        {
            if (item.Equals(newOrder))
            {
                repeat = true;
            }
        }
        if (!repeat)
        {
            data.Add(newOrder);
            Console.WriteLine("订单创建成功。");
        }
        else
        {
            Console.WriteLine("订单创建失败，有重复订单。");
        }
    }
    public void del()
    {
        Console.WriteLine("请输入需要删除的订单Id：");
        int id = Int32.Parse(Console.ReadLine());
        try
        {
            bool done = false;
            Order toDel = null; // 不能在foreach语句内修改集合
            data.ForEach(m => { if (m.Id == id) { toDel = m; done = true; } });
            if (!done)
            {
                throw new SomeException("删除失败", 1);
            }
            data.Remove(toDel);
            Console.WriteLine("删除完毕。");
        }
        catch (SomeException e)
        {
            Console.WriteLine(e.Message + ", 错误代码: " + e.Code);
        }  
    }
    public void modify()
    {
        Console.WriteLine("请输入需要修改的订单Id：");
        int id = Int32.Parse(Console.ReadLine());
        Console.WriteLine("修改(int)Id 请输入1 , 修改(string)ProductName 请输入2 , 修改(string)Customer 请输入3 , 修改(int)Sum 请输入4 , 修改(int)Quantity 请输入5 , 修改(int)Price 请输入6");
        int i = Int32.Parse(Console.ReadLine());
        switch (i)
        {
            case 1:
                try
                {
                    Console.WriteLine("请输入(int)Id：");
                    bool find = false;
                    bool repeat = false;
                    data.ForEach(m => { if (m.Id == id) {
                            find = true;
                            data.ForEach(n =>
                            {
                                if (n.Equals(m))
                                {
                                    repeat = true;
                                }
                            });
                            if (repeat)
                                throw new SomeException("修改失败，原因是修改后出现了重复订单", 3);
                            m.Id = Int32.Parse(Console.ReadLine()); } });
                    if (!find)
                        throw new SomeException("修改失败，原因是没找到对应id的订单", 2);
                }
                catch(SomeException e)
                {
                    Console.WriteLine(e.Message + ", 错误代码: " + e.Code);
                }
                break;
            case 2:
                Console.WriteLine("请输入(string)ProductName：");
                data.ForEach(m => { if (m.Id == id) { m.Details.ProductName = Console.ReadLine(); } });
                break;
            case 3:
                Console.WriteLine("请输入(string)Customer：");
                data.ForEach(m => { if (m.Id == id) { m.Customer = Console.ReadLine(); } });
                break;
            case 4:
                Console.WriteLine("请输入(int)Sum：");
                data.ForEach(m => { if (m.Id == id) { m.Sum = Int32.Parse(Console.ReadLine()); } });
                break;
            case 5:
                Console.WriteLine("请输入(int)Quantity：");
                data.ForEach(m => { if (m.Id == id) { m.Details.Quantity = Int32.Parse(Console.ReadLine()); } });
                break;
            case 6:
                Console.WriteLine("请输入(int)Price：");
                data.ForEach(m => { if (m.Id == id) { m.Details.Price = Int32.Parse(Console.ReadLine()); } });
                break;
            default:
                Console.WriteLine("输入错误，修改失败。");
                break;
        }

    }
    public void search()
    {
        Console.WriteLine("按(int)Id 查询请输入1 , 按(string)ProductName 查询请输入2 , 按(string)Customer 查询请输入3 , 按(int)Sum 查询请输入4");
        string str = Console.ReadLine();
        int i = Int32.Parse(str);
        switch (i)
        {
            case 1:
                Console.WriteLine("请输入(int)Id");
                str = Console.ReadLine();
                int id = Int32.Parse(str);
                var query1 = from n in data
                             where n.Id == id
                             orderby n.Sum descending
                             select n;
                if (query1.Count() > 0)
                {
                    Console.WriteLine("查询结果：");
                    List<Order> list = query1.ToList();
                    list.ForEach(m => Console.WriteLine(m.ToString()));
                }
                else
                {
                    Console.WriteLine("查询结果为空");
                }
                break;
            case 2:
                Console.WriteLine("请输入(string)ProductName");
                str = Console.ReadLine();
                var query2 = from n in data
                             where n.Details.ProductName == str
                             orderby n.Sum descending
                             select n;
                if (query2.Count() > 0)
                {
                    Console.WriteLine("查询结果：");
                    List<Order> list = query2.ToList();
                    list.ForEach(m => Console.WriteLine(m.ToString()));
                }
                else
                {
                    Console.WriteLine("查询结果为空");
                }
                break;
            case 3:
                Console.WriteLine("请输入(string)Customer");
                str = Console.ReadLine();
                var query3 = from n in data
                             where n.Customer == str
                             orderby n.Sum descending
                             select n;
                if (query3.Count() > 0)
                {
                    Console.Write("查询结果：");
                    List<Order> list = query3.ToList();
                    list.ForEach(m => Console.WriteLine(m.ToString()));
                }
                else
                {
                    Console.WriteLine("查询结果为空");
                }
                break;
            case 4:
                Console.WriteLine("请输入(int)Sum");
                str = Console.ReadLine();
                int sum = Int32.Parse(str);
                var query4 = from n in data
                             where n.Sum == sum
                             orderby n.Sum descending
                             select n;
                if (query4.Count() > 0)
                {
                    Console.Write("查询结果：");
                    List<Order> list = query4.ToList();
                    list.ForEach(m => Console.WriteLine(m.ToString()));
                }
                else
                {
                    Console.WriteLine("查询结果为空");
                }
                break;
            default:
                Console.WriteLine("输入有误，请重新输入。");
                break;
        }
    }
    public void Sort()
    {
        data.Sort();
    }
    public void Sort(System.Collections.Generic.IComparer<Order> f)
    {
        data.Sort(f);
    }
    public void Export()
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
        using (FileStream fs = new FileStream("order.xml", FileMode.Create))
        {
            xmlSerializer.Serialize(fs, data);
        }
        Console.WriteLine("\nSerialized as XML: ");
        foreach (string line in File.ReadLines(@"order.xml", Encoding.UTF8))
        {
            Console.WriteLine(line);
        }
        Console.WriteLine(File.ReadAllText("order.xml"));
    }
    public void Import()
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Order>));
        using (FileStream fs = new FileStream("order.xml", FileMode.Open))
        {
            data = (List<Order>)xmlSerializer.Deserialize(fs);
            Console.WriteLine("\nDeserialized as XML: ");
            data.ForEach(m => Console.WriteLine(m));
        }
    }
}
public class Program
{
    public static void Main()
    {
        OrderService service = new OrderService();
        int i = 1;
        while (i > 0)
        {
            Console.WriteLine("主界面，输入1添加订单，输入2删除订单，输入3修改订单，输入4查询订单，输入5排序订单，输入6将订单序列化为Xml文件，输入7从Xml载入订单，输入0或负数退出程序");
            i = Int32.Parse(Console.ReadLine());
            switch (i)
            {
                case 1:
                    service.add();
                    break;
                case 2:
                    service.del();
                    break;
                case 3:
                    service.modify();
                    break;
                case 4:
                    service.search();
                    break;
                case 5:
                    service.Sort();
                    break;
                case 6:
                    service.Export();
                    break;
                case 7:
                    service.Import();
                    break;
                default:
                    Console.WriteLine("程序退出");
                    break;
            }
        }
    }
}